﻿using LitJson;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Stone : Ship
{
    public enum StoneLevel
    {
        LEVLE_1,
        LEVLE_2,
        LEVLE_3,
        LEVLE_4,
    }
    public StoneLevel m_StoneLevel= StoneLevel.LEVLE_1;
    public string m_Kind = "NONE";
    public float m_Purity = 1;

    float m_MinMass=1;
    float m_MaxMass =2;
    float m_Mass=1;
    bool IsLoaded = false;
    public Dictionary<Item.ItemsType, float> OreContentList = new Dictionary<Item.ItemsType, float>();
    protected override void Awake()
    {
        base.Awake();
        if(!IsLoaded)
        {
            
            m_Purity = RandomFromDistribution.RandomRangeSlope(1, 100, 10, RandomFromDistribution.Direction_e.Left);

            InitMassRange();
            m_Mass = RandomFromDistribution.RandomRangeNormalDistribution(m_MinMass, m_MaxMass, RandomFromDistribution.ConfidenceLevel_e._999);

            if (GetComponent<Rigidbody2D>())
                GetComponent<Rigidbody2D>().mass = m_Mass;
            InitScale();
        }
        transform.rotation = Quaternion.AngleAxis(Random.Range(0, 360), new Vector3(0, 0, 1));
    }

    new void Start()
    {
        base.Start();
    }

    // Update is called once per frame
    new void Update()
    {
        base.Update();
    }

    public override JsonData save()
    {
        var rootJson = base.save();

        rootJson["Mass"] = m_Mass;

        rootJson["Purity"] = m_Purity;

        var contentScale = new JsonData();
        contentScale.SetJsonType(JsonType.Object);
        rootJson["ContentScale"] = contentScale;
        foreach(var content in OreContentList)
        {
            contentScale[content.Key.ToString()] = content.Value;
        }

        return rootJson;
    }
    public override bool load(JsonData rootJson)
    {
        if (false == base.load(rootJson))
            return false;

        IDictionary<string, JsonData> jsond = rootJson.ValueAsObject();

        if (jsond.ContainsKey("Mass"))
            m_Mass = (float)jsond["Mass"].ValueAsDouble();

        if (jsond.ContainsKey("Purity"))
            m_Purity = (float)jsond["Purity"].ValueAsDouble();

        // 矿物含量加载
        if (jsond.ContainsKey("ContentScale"))
        {
            IDictionary<string, JsonData> contentScaled = jsond["ContentScale"].ValueAsObject();
            foreach (var content in contentScaled)
            {
                OreContentList.Add(ItemFactory.Instance.GetItemType(content.Key), (float)content.Value.ValueAsDouble());
            }
        }

        if (GetComponent<Rigidbody2D>())
            GetComponent<Rigidbody2D>().mass = m_Mass;
        InitMassRange();
        InitScale();

        m_ShipStruct.m_Price = (int)(m_Purity * m_Mass);
        IsLoaded = true;

        return true;
    }

    public void InitContent(MineFiled filed)
    {
        if(null == filed || OreContentList.Count != 0)
        {
            return;
        }
        foreach (var item in filed.ProductionList)
        {
            if(!OreContentList.ContainsKey(item.Key))
                OreContentList.Add(item.Key,
                    RandomFromDistribution.RandomRangeNormalDistribution(0, item.Value, RandomFromDistribution.ConfidenceLevel_e._999));
        }
    }
    public void StoneCutting()
    {
        Player.Instance.RemoveShip(this);

        float allContentScale = 0;
        foreach (var content in OreContentList)
        {
            allContentScale += content.Value;
        }

        foreach (var content in OreContentList)
        {
            int number = CalcNumber(content.Value / allContentScale);
            if (number >= 1)
            {
                Player.Instance.addItem(content.Key, number);

                var item = ItemFactory.Instance.createItem(content.Key.ToString());
                MessageShow.Instance.Messaage("切出\""+item.Name+"x"+number+"\"", new Vector4(1,1,1,1), true);
            }
        }
        Destroy(gameObject);
    }

    int CalcNumber(float scale)
    {
        return (int)((scale * m_Mass * 0.7 * (m_Purity * 0.05f)));
    }
    public void StoneExplosion()
    {
        if (gameObject == null ||
            this == null || 
            m_ShipStruct.StructurePoint > 0)
            return;
        float allContentScale = 0;
        foreach (var content in OreContentList)
        {
            allContentScale += content.Value;
        }

        List<Item> items = new List<Item>();
        foreach (var content in OreContentList)
        {
            int number = CalcNumber(content.Value / allContentScale ) / 2;
            if (number >= 1)
            {
                var item = ItemFactory.Instance.createItem(content.Key.ToString());
                item.m_Number = number;

                var objPerfab = Resources.Load<GameObject>(item.PerfabPath);
                if(objPerfab)
                {
                    for (int i = 0; i < number; ++i)
                    {
                        var stone  = Instantiate(objPerfab).GetComponent<Stone>();
                        if(stone)
                        {
                            var dir = new Vector3(Random.Range(0f, 1f), Random.Range(0f,1f), 0);
                            dir = dir.normalized;
                            stone.transform.position = transform.position;
                        }
                    }
                }
            }
        }

    }

    void InitScale()
    {
        float scale = (m_Mass - m_MinMass) / (m_MaxMass - m_MinMass) * 1.5f + 0.5f;
        if(scale <0.5  || scale > 2)
        {
            return;
        }
        transform.localScale = new Vector3(scale, scale, 1);

        m_ShipStruct.StructurePointMax *= scale;
        m_ShipStruct.StructurePoint = m_ShipStruct.StructurePointMax;
    }
    void InitMassRange()
    {
        switch (m_StoneLevel)
        {
            case StoneLevel.LEVLE_2:
                m_MinMass = 15;
                m_MaxMass = 45;
                break;
            case StoneLevel.LEVLE_3:
                m_MinMass = 55;
                m_MaxMass = 140;
                break;
            case StoneLevel.LEVLE_4:
                m_MinMass = 200;
                m_MaxMass = 600;
                break;
        }
    }

    protected override void OnDestroy()
    {
        if(m_StoneLevel == StoneLevel.LEVLE_2)
            StoneExplosion();
        base.OnDestroy();
    }
}
